package com.ihr360.payroll.service.payroll.mock.core;

import com.google.common.collect.ImmutableList;
import com.ihr360.alps.api.ServiceProvider;
import com.ihr360.commons.model.type.FieldSource;
import com.ihr360.commons.model.type.NumOperation;
import com.ihr360.commons.model.type.RoundingMode;
import com.ihr360.commons.model.type.SalaryFieldValueType;
import com.ihr360.expr.engine.VariableID;
import com.ihr360.payroll.model.dto.salary.embeddable.SalaryFieldValue;
import com.ihr360.payroll.model.dto.salary.meta.SalaryField;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public abstract class SalaryFieldHelper {
    private static void addToSalaryFields(Map<String, SalaryField> salaryFieldMap, SalaryField field) {
        salaryFieldMap.put(field.getCode(), field);
    }

    public static List<SalaryField> salaryFieldList() {
        return salaryFields().get(0).values().stream().collect(Collectors.toList());
    }


    public static List<Map<String, SalaryField>> salaryFields() {
        Map<String, SalaryField> salaryFieldMap = new HashMap();
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.basesalary());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.positionsalary());

        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.backpaysalary());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.salaryadjustment());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.eehf());

        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.erpension());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.eepension());

        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.hfee());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.scee());

        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.adjustmentforattendance());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.otsalary());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.unpaidleavededuction());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.sickleavededuction());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.sickleavedeductiontmp1());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.unpaidleavedeductiontmp1());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.sickcalcbase());


        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.phasedsalaryadjustment());

        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.salarybeforetax());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.taxablesalary());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.salarytaxtable());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.salarytax());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.servicechargetax());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.taxrate());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.taxreduce());
        //工龄工资
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.senioritypay());
        //岗位津贴
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.positionallowance());
        //月度奖金
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.monthlybonus());
        //餐补
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.mealallowance());

        //自定义字段
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.grosssalary());

        //年终奖金部分

        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.annualbonusspecial());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.annualBonusTaxTable());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.taxableannualbonusspecial());
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.yearendbonustax());

        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.netpayannualbonus());


        //输入项目,标准项目
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.dailymeal());

        //交通补贴
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.transportationallowance());

        //出差津贴
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.travelincentive());

        //迟到扣款
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.latededuction());

        //税后报销
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.claimaftertax());

        //病假扣款比例
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.sickleavedeductionrate());

        //加班饭贴
        addToSalaryFields(salaryFieldMap, SalaryFieldHelper.otmealallowance());


        return ImmutableList.of(salaryFieldMap);
    }

    //--------------------------------------------------------
    //合计项目
    //--------------------------------------------------------


    //--------------------------------------------------------
    //引用项目
    //--------------------------------------------------------

    /**
     * 基本工资
     *
     * @return
     */
    public static SalaryField basesalary() {
        SalaryField field = new SalaryField();
        String fieldName = "basesalary";
        field.setCode(fieldName);
        field.setName("基本工资");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();


        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 岗位工资
     *
     * @return
     */
    public static SalaryField positionsalary() {
        SalaryField field = new SalaryField();
        String fieldName = "positionsalary";
        field.setCode(fieldName);
        field.setName("岗位工资");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 工龄工资
     *
     * @return
     */
    public static SalaryField senioritypay() {
        SalaryField field = new SalaryField();
        String fieldName = "senioritypay";
        field.setCode(fieldName);
        field.setName("工龄工资");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //=IF(G3<0,0,IF(G3<=5,100*ROUNDDOWN(G3,0),150*ROUNDDOWN(G3,0)))
        value.setFormula("=IF(STAFF_ROSTER$enrollWorkYears<0,0,IF(STAFF_ROSTER$enrollWorkYears<=5,100*ROUNDDOWN(STAFF_ROSTER$enrollWorkYears,0),150*ROUNDDOWN(STAFF_ROSTER$enrollWorkYears,0)))");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 岗位津贴
     */
    public static SalaryField positionallowance() {
        SalaryField field = new SalaryField();
        String fieldName = "positionallowance";
        field.setCode(fieldName);
        field.setName("岗位津贴");
        field.setType(SalaryFieldTypeHelper.pretaxallowance());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 交通补贴
     */
    public static SalaryField transportationallowance() {
        SalaryField field = new SalaryField();
        String fieldName = "transportationallowance";
        field.setCode(fieldName);
        field.setName("交通补贴");
        field.setType(SalaryFieldTypeHelper.aftertaxexpenses());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 餐费补贴
     */
    public static SalaryField mealallowance() {
        SalaryField field = new SalaryField();
        String fieldName = "mealallowance";
        field.setCode(fieldName);
        field.setName("餐费补贴");
        field.setType(SalaryFieldTypeHelper.pretaxallowance());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //20*出勤天数
        value.setFormula("=日饭贴标准*ATT_M_R$workingdays");
        field.setValueMeta(value);
        return field;
    }


    //--------------------------------------------------------------
    //输入项目
    //--------------------------------------------------------------


    /**
     * 日饭贴标准
     *
     * @return
     */
    public static SalaryField dailymeal() {
        SalaryField field = new SalaryField();
        String fieldName = "日饭贴标准";
        field.setName("日饭贴标准");
        field.setType(SalaryFieldTypeHelper.other());

        field.setCode(fieldName);
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 补发工资
     *
     * @return
     */
    public static SalaryField backpaysalary() {
        SalaryField field = new SalaryField();
        String fieldName = "backpaysalary";
        field.setName("补发工资");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setCode(fieldName);
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
//        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 加班饭贴
     *
     * @return
     */
    public static SalaryField otmealallowance() {
        SalaryField field = new SalaryField();
        String fieldName = "加班饭贴";
        field.setName("加班饭贴");
        field.setType(SalaryFieldTypeHelper.pretaxallowance());

        field.setCode(fieldName);
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
//        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 出差津贴
     *
     * @return
     */
    public static SalaryField travelincentive() {
        SalaryField field = new SalaryField();
        String fieldName = "travelincentive";
        field.setName("出差津贴");
        field.setType(SalaryFieldTypeHelper.pretaxallowance());

        field.setCode(fieldName);
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
//        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 迟到扣款
     *
     * @return
     */
    public static SalaryField latededuction() {
        SalaryField field = new SalaryField();
        String fieldName = "迟到扣款";
        field.setName("迟到扣款");
        field.setType(SalaryFieldTypeHelper.pretaxdeduction());

        field.setCode(fieldName);
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
//        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 税后报销
     *
     * @return
     */
    public static SalaryField claimaftertax() {
        SalaryField field = new SalaryField();
        String fieldName = "税后报销";
        field.setName("税后报销");
        field.setType(SalaryFieldTypeHelper.aftertaxexpenses());

        field.setCode(fieldName);
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
//        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }


    /**
     * 月度奖金
     *
     * @return
     */
    public static SalaryField monthlybonus() {
        SalaryField field = new SalaryField();
        String fieldName = "monthlybonus";
        field.setType(SalaryFieldTypeHelper.bonus());

        field.setCode(fieldName);
        field.setName("月度奖金");
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }


    /**
     * 薪资调整
     *
     * @return
     */
    public static SalaryField salaryadjustment() {
        SalaryField field = new SalaryField();
        String fieldName = "salaryadjustment";
        field.setCode(fieldName);
        field.setName("薪资调整");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 其他应税调整
     */
    public static SalaryField othertaxableincome() {
        SalaryField field = new SalaryField();
        String fieldName = "othertaxableincome";
        field.setCode(fieldName);
        field.setName("其他应税调整");
        field.setType(SalaryFieldTypeHelper.taxableadjustment());

        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());

        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    //-----------------------------------------------------------
    //社保公积金项目
    //------------------------------------------------------------

    /**
     * 公积金个人
     */
    public static SalaryField eehf() {
        SalaryField field = new SalaryField();
        String fieldName = "eehf";
        field.setCode(fieldName);
        field.setName("公积金个人");
        field.setType(SalaryFieldTypeHelper.personsihf());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(null);

        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.SIHF, "HF_TYPE_0001_P"));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 公积金个人合计
     */
    public static SalaryField hfee() {
        SalaryField field = new SalaryField();
        String fieldName = "hfee";
        field.setCode(fieldName);
        field.setName("公积金个人合计");
        field.setType(SalaryFieldTypeHelper.statistics());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.SIHF, "hfee"));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 养老公司
     */
    public static SalaryField erpension() {
        SalaryField field = new SalaryField();
        String fieldName = "erpension";
        field.setCode(fieldName);
        field.setName("养老公司");
        field.setType(SalaryFieldTypeHelper.companysihf());

        field.setSource(FieldSource.FUNCTION);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(null);
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.SIHF, "SI_TYPE_0001_C"));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 养老个人
     */
    public static SalaryField eepension() {
        SalaryField field = new SalaryField();
        String fieldName = "eepension";
        field.setCode(fieldName);
        field.setName("养老个人");
        field.setType(SalaryFieldTypeHelper.personsihf());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(null);
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.SIHF, "SI_TYPE_0001_P"));
        field.setValueMeta(value);
        return field;
    }

    /**
     * 社保个人合计
     */
    public static SalaryField scee() {
        SalaryField field = new SalaryField();
        String fieldName = "scee";
        field.setCode(fieldName);
        field.setName("社保个人合计");
        field.setType(SalaryFieldTypeHelper.statistics());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(null);
        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.SIHF, "scee"));
        field.setValueMeta(value);
        return field;
    }


    //--------------------------------------------------------------
    //考勤相关工资项目
    //--------------------------------------------------------------

    /**
     * 入离职调整
     *
     * @return
     */
    public static SalaryField adjustmentforattendance() {
        SalaryField field = new SalaryField();
        String fieldName = "adjustmentforattendance";
        field.setCode(fieldName);
        field.setName("入离职调整");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //入离职调整基数*工作天数/月标准工作日-入离职调整基数
       // value.setFormula("=$SAL_ADJUST_RULE$calcBase*ATT_M_R$paiddays/$SAL_ADJUST_RULE$monthWorkCount-$SAL_ADJUST_RULE$calcBase");
        field.setValueMeta(value);
        return field;
    }

//    //入离职调整基数*工作天数/月标准工作日 + 入离职调整基数*(月标准工作日-工作天数)/月标准工作日-入离职调整基数
//    value.setFormula("=$SAL_ADJUST_RULE$calcBase*ATT_M_R$paiddays/$SAL_ADJUST_RULE$monthWorkCount+" +
//            "$SAL_ADJUST_RULE$calcBase*($SAL_ADJUST_RULE$monthWorkCount-ATT_M_R$paiddays)/$SAL_ADJUST_RULE$monthWorkCount-$SAL_ADJUST_RULE$calcBase");


    /**
     * 加班工资
     *
     * @return
     */
    public static SalaryField otsalary() {
        SalaryField field = new SalaryField();
        String fieldName = "otsalary";
        field.setCode(fieldName);
        field.setName("加班工资");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        value.setFormula("=$SAL_OT_RULE$STANDARD_calcBase/$SAL_OT_RULE$STANDARD_monthWorkCount/$SAL_OT_RULE$STANDARD_dayWorkCount*($SAL_OT_RULE$STANDARD_numOpRatio*ATT_M_R$othours150+$SAL_OT_RULE$STANDARD_weekendRatio*ATT_M_R$othours200+$SAL_OT_RULE$STANDARD_holidayRatio*ATT_M_R$othours300)");
        value.setPhasedFormula("=PHASE1!otsalary+PHASE2!otsalary");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 病假扣款
     *
     * @return
     */
    public static SalaryField unpaidleavedeductiontmp1() {
        SalaryField field = new SalaryField();
        String fieldName = "unpaidleavedeductiontmp1";
        field.setCode(fieldName);
        field.setName("事假扣款");
        field.setType(SalaryFieldTypeHelper.other());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //TODO:
        value.setFormula("=$SAL_PL_RULE$monthWorkCount*$SAL_PL_RULE$dayWorkCount");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 病假扣款
     *
     * @return
     */
    public static SalaryField sickcalcbase() {
        SalaryField field = new SalaryField();
        String fieldName = "sickcalcbase";
        field.setCode(fieldName);
        field.setName("事假扣款");
        field.setType(SalaryFieldTypeHelper.other());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //TODO:
        value.setFormula("=$SAL_SL_RULE$calcBase");
        field.setValueMeta(value);
        return field;
    }


    /**
     * 事假扣款
     *
     * @return
     */
    public static SalaryField unpaidleavededuction() {
        SalaryField field = new SalaryField();
        String fieldName = "unpaidleavededuction";
        field.setCode(fieldName);
        field.setName("事假扣款");
        field.setType(SalaryFieldTypeHelper.pretaxdeduction());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //TODO:
        value.setFormula("=$SAL_PL_RULE$calcBase*$SAL_PL_RULE$baseRatio/($SAL_PL_RULE$monthWorkCount*$SAL_PL_RULE$dayWorkCount)*ATT_M_R$unpaidleavecnt");
        value.setPhasedFormula("=PHASE1!unpaidleavededuction+PHASE2!unpaidleavededuction");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 病假扣款
     *
     * @return
     */
    public static SalaryField sickleavedeductiontmp1() {
        SalaryField field = new SalaryField();
        String fieldName = "sickleavedeductiontmp1";
        field.setCode(fieldName);
        field.setName("病假扣款");
        field.setType(SalaryFieldTypeHelper.other());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //TODO:
        value.setFormula("=$SAL_SL_RULE$monthWorkCount*$SAL_SL_RULE$dayWorkCount");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 病假扣款
     *
     * @return
     */
    public static SalaryField sickleavededuction() {
        SalaryField field = new SalaryField();
        String fieldName = "sickleavededuction";
        field.setCode(fieldName);
        field.setName("病假扣款");
        field.setType(SalaryFieldTypeHelper.pretaxdeduction());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //TODO:
        value.setFormula("=$SAL_SL_RULE$calcBase/($SAL_SL_RULE$monthWorkCount*$SAL_SL_RULE$dayWorkCount)*sickleavedeductionrate*ATT_M_R$sickleavecnt");
        value.setPhasedFormula("=PHASE1!sickleavededuction+PHASE2!sickleavededuction");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 病假扣款比例
     *
     * @return
     */
    public static SalaryField sickleavedeductionrate() {
        SalaryField field = new SalaryField();
        String fieldName = "sickleavedeductionrate";
        field.setCode(fieldName);
        field.setName("病假扣款比例");
        field.setType(SalaryFieldTypeHelper.other());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //TODO:
        value.setFormula("=HLOOKUP(STAFF_ROSTER$enrollWorkYears,{0,2.001,4,6,8.001;0.4,0.3,0.2,0.1,0},2)");

        field.setValueMeta(value);
        return field;
    }


    //---------------
    //分段计薪调整
    //---------------

    /**
     * 分段计薪调整(调薪调整)--分段计薪调整只关系薪资周期内的分段带来的调整。不关系薪资后期之外的分段
     *
     * @return
     */
    public static SalaryField phasedsalaryadjustment() {
        SalaryField field = new SalaryField();
        String fieldName = "phasedsalaryadjustment";
        field.setCode(fieldName);
        field.setName("分段计薪调整");
        field.setType(SalaryFieldTypeHelper.salary());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.salaryTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);

        //公式问题，ATT_M_R$paiddays 这个在薪资周期和考勤周期不一致的时候，不能取这个值作为分段的时间，需要获取薪资周期内的分段，并做分段处理

        value.setFormula("=(PHASE1!basesalary+PHASE1!positionallowance)*PHASE1!legalpaiddays/$SAL_ADJUST_RULE$monthWorkCount+(PHASE2!basesalary+PHASE2!positionallowance)*($SAL_ADJUST_RULE$monthWorkCount-PHASE1!legalpaiddays)/$SAL_ADJUST_RULE$monthWorkCount-(basesalary+positionallowance)");

        field.setValueMeta(value);
        return field;
    }

    /**
     * 法定计薪天数
     *
     * @return
     */
    public static SalaryField legalpaiddays() {
        SalaryField field = new SalaryField();
        String fieldName = "legalpaiddays";
        field.setCode(fieldName);
        field.setName("法定计薪天数");
        field.setType(SalaryFieldTypeHelper.attendance());

        field.setSource(FieldSource.FUNCTION);
        SalaryFieldValue value = new SalaryFieldValue();
        field.setValueMeta(value);
        return field;
    }


    //------------
    //计算结果
    //------------

    /**
     * 税前合计
     */
    public static SalaryField grosssalary() {
        SalaryField field = new SalaryField();
        String fieldName = "grosssalary";
        field.setCode(fieldName);
        field.setName("税前合计");
        field.setType(SalaryFieldTypeHelper.statistics());

        field.setSource(FieldSource.FUNCTION);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //工资合计+奖金合计+税前津补贴+应税调整-税前扣款
        value.setFormula("=salarytotal+bonustotal+pretaxallowancetotal+taxableadjustmenttotal-pretaxdeductiontotal");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 应税工资
     */
    public static SalaryField salarybeforetax() {
        SalaryField field = new SalaryField();
        String fieldName = "salarybeforetax";
        field.setCode(fieldName);
        field.setName("应税工资");
        field.setType(SalaryFieldTypeHelper.statistics());

        field.setSource(FieldSource.FUNCTION);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //基本工资+岗位工资+岗位津贴+工龄工资+饭补+月度奖金-社保个人合计-公积金个人合计+入离职调整
        value.setFormula("=grosssalary-hfee-scee");
        //value.setFormula("=basesalary+positionsalary");
        //value.setFormula("=16585.1");
        field.setValueMeta(value);
        return field;
    }

    /**
     * 工资薪金税表
     */
    public static SalaryField salarytaxtable() {
        SalaryField field = new SalaryField();
        String fieldName = "salarytaxtable";
        field.setCode(fieldName);
        field.setName("工资薪金税表");
        field.setType(SalaryFieldTypeHelper.other());


        field.setSource(FieldSource.FUNCTION);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setValueType(SalaryFieldValueType.ARRAY);
        value.setFormula("=$TAX_TABLE$salary_tax");

        field.setValueMeta(value);
        return field;
    }

    /**
     * 年终奖金税表
     *
     * @return
     */
    public static SalaryField annualBonusTaxTable() {
        SalaryField field = new SalaryField();
        String fieldName = "annualbonustaxtable";
        field.setCode(fieldName);
        field.setName("年终奖金税表");
        field.setType(SalaryFieldTypeHelper.other());

        field.setSource(FieldSource.FUNCTION);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setValueType(SalaryFieldValueType.ARRAY);
        value.setFormula("=$TAX_TABLE$annual_bonus_tax");
        field.setValueMeta(value);
        return field;
    }

    //[1-收入下限,2-收入上限,3-固定免税扣除额,4-免税扣除比例,5-应纳税所得额下限,6-应纳税所得额上限,7-税率,8-速算扣除数]

    /**
     * 应纳税额
     */
    public static SalaryField taxablesalary() {
        SalaryField field = new SalaryField();
        String fieldName = "taxablesalary";
        field.setCode(fieldName);
        field.setName("应纳税额");
        field.setType(SalaryFieldTypeHelper.statistics());

        field.setSource(FieldSource.FUNCTION);
        SalaryFieldValue value = new SalaryFieldValue();
        //基本工资+岗位工资-社保个人合计-公积金个人合计+其他应税调整
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //应税工资-固定扣除额-扣除比例
        value.setFormula("=IF(salarybeforetax-VLOOKUP(salarybeforetax,salarytaxtable,3)-salarybeforetax*VLOOKUP(salarybeforetax,salarytaxtable,4)>0,salarybeforetax-VLOOKUP(salarybeforetax,salarytaxtable,3)-salarybeforetax*VLOOKUP(salarybeforetax,salarytaxtable,4),0)");

        field.setValueMeta(value);
        return field;
    }

    /**
     * 税率
     */
    public static SalaryField taxrate() {
        SalaryField field = new SalaryField();
        String fieldName = "taxrate";
        field.setCode(fieldName);
        field.setName("税率");
        field.setType(SalaryFieldTypeHelper.other());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        SalaryFieldValue value = new SalaryFieldValue();
        //TODO:
        //=ROUND(应纳税额*税率-速扣数,2)
        value.setFormula("=VLOOKUP(salarybeforetax,salarytaxtable,7)");
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 速算扣除数
     */
    public static SalaryField taxreduce() {
        SalaryField field = new SalaryField();
        String fieldName = "taxreduce";
        field.setCode(fieldName);
        field.setName("速算扣除数");
        field.setType(SalaryFieldTypeHelper.other());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setPattern(2);
        value.setFormula("=VLOOKUP(salarybeforetax,salarytaxtable,8)");

        field.setValueMeta(value);
        return field;
    }

    /**
     * 工资薪金税
     */
    public static SalaryField salarytax() {
        SalaryField field = new SalaryField();
        String fieldName = "salarytax";
        field.setCode(fieldName);
        field.setName("工资薪金税");
        field.setType(SalaryFieldTypeHelper.tax());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        //TODO:
        //=ROUND(应纳税额*税率-速扣数,2)
        //value.setFormula("=taxablesalary*taxrate-VLOOKUP(salarybeforetax,salarytaxtable,3)");
        value.setFormula("=taxablesalary*VLOOKUP(salarybeforetax,salarytaxtable,7)-VLOOKUP(salarybeforetax,salarytaxtable,8)");

        field.setValueMeta(value);
        return field;
    }

    /**
     * 劳务税
     */
    public static SalaryField servicechargetax() {
        SalaryField field = new SalaryField();
        String fieldName = "servicechargetax";
        field.setCode(fieldName);
        field.setName("劳务税");
        field.setType(SalaryFieldTypeHelper.tax());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        SalaryFieldValue value = new SalaryFieldValue();
        //TODO:
        //value.setFormula("=" + VariableID.build(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));

        field.setValueMeta(value);
        return field;
    }


    //======================
    //奖金部分
    //======================

    /**
     * 年终奖金所得额
     */
    public static SalaryField annualbonusspecial() {
        SalaryField field = new SalaryField();
        String fieldName = "annualbonusspecial";
        field.setName("年终奖金");
        field.setType(SalaryFieldTypeHelper.tax());

        field.setCode(fieldName);
        field.setSource(FieldSource.INPUT);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.annualBonusTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
//        value.setFormula("=" + VariableID.buildVariableId(ServiceProvider.SERVICE_ID.STAFF_SALARY, fieldName));
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }

    /**
     * 年终奖应纳税额
     */
    public static SalaryField taxableannualbonusspecial() {
        SalaryField field = new SalaryField();
        String fieldName = "taxableannualbonusspecial";
        field.setName("年终奖应纳税额");
        field.setType(SalaryFieldTypeHelper.statistics());

        field.setCode(fieldName);
        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.ADD);
        field.setTaxType(TaxTypeHelper.annualBonusTaxType());
        SalaryFieldValue value = new SalaryFieldValue();
        value.setFormula("=IF(taxablesalary>0,annualbonusspecial,IF(annualbonusspecial-(VLOOKUP(salarybeforetax,$TAX_TABLE$salary_tax,3)-salarybeforetax)<=0,0,annualbonusspecial-(VLOOKUP(salarybeforetax,$TAX_TABLE$salary_tax,3)-salarybeforetax)))");
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);
        field.setValueMeta(value);
        return field;
    }


    /**
     * 年终奖税
     */
    public static SalaryField yearendbonustax() {
        SalaryField field = new SalaryField();
        String fieldName = "yearendbonustax";
        field.setCode(fieldName);
        field.setName("年终奖税");
        field.setType(SalaryFieldTypeHelper.tax());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);

        value.setFormula("=taxableannualbonusspecial*VLOOKUP(annualbonusspecial/12,annualbonustaxtable,7)-VLOOKUP(annualbonusspecial/12,annualbonustaxtable,8)");

        field.setValueMeta(value);
        return field;
    }

    /**
     * 实发年终奖
     */
    public static SalaryField netpayannualbonus() {
        SalaryField field = new SalaryField();
        String fieldName = "netpayannualbonus";
        field.setCode(fieldName);
        field.setName("实发年终奖");
        field.setType(SalaryFieldTypeHelper.tax());

        field.setSource(FieldSource.FUNCTION);
        field.setPersonalSalaryNumOp(NumOperation.SUBTRACT);
        SalaryFieldValue value = new SalaryFieldValue();
        value.setRoundingMode(RoundingMode.ROUND);
        value.setPattern(2);

        value.setFormula("=annualbonusspecial-yearendbonustax");

        field.setValueMeta(value);
        return field;
    }

    /**
     * 自定义薪资字段
     */


}
